package com.star.rpc.serializer;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * packageName com.star.rpc.serializer
 *
 * @author zerostart
 * @className KryoSerializer
 * @date 2024/11/20
 * @description kryo 序列化器
 *
 * 默认情况下，Kryo 要求在序列化和反序列化对象之前，必须先注册所有涉及的类。
 * 这可以通过 kryo.register(Class) 方法来完成。注册类有助于 Kryo 更高效地处理序列化和反序列化过程，
 */
public class KryoSerializer implements Serializer {


    private static final ThreadLocal<Kryo> KRYO_THREAD_LOCAL = ThreadLocal.withInitial(()-> {
        Kryo kryo = new Kryo();
        // 设置动态序列化和反序列化类，不提前注册所有类
        kryo.setRegistrationRequired(false);
        return kryo;
    });

    @Override
    public <T> byte[] serialize(T object) throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Output output = new Output(byteArrayOutputStream);
        KRYO_THREAD_LOCAL.get().writeObject(output, object);
        output.close();
        return byteArrayOutputStream.toByteArray();
    }

    @Override
    public <T> T deserialize(byte[] bytes, Class<T> clazz) throws Exception {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        Input input = new Input(byteArrayInputStream);
        T object = KRYO_THREAD_LOCAL.get().readObject(input, clazz);
        input.close();
        return object;
    }
}
